use std::{
    fs::{self, File, OpenOptions},
    io::{BufReader, BufWriter, Write},
};

use clap::Parser;
use indicatif::{ProgressBar, ProgressStyle};
use serde_json::{to_string, Deserializer, Value};
use serde_jsonlines::append_json_lines;

#[derive(Debug, Parser)]
#[clap(
    name = "converter",
    bin_name = "converter2jsonl",
    long_about = "转换文件为jsonl"
)]
#[clap(author, version, about="文件转换器", long_about = None)]
struct App {
    input: String,
    output: Option<String>,
}

fn main() -> anyhow::Result<()> {
    let app = App::parse();
    let md = fs::metadata(app.input.clone())?;
    let reader = BufReader::new(File::open(app.input)?);
    let output = app.output.clone().unwrap_or("output.jsonl".to_string());
    let pb = ProgressBar::new(md.len());
    pb.set_style(ProgressStyle::default_bar()
        .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})")?
        .progress_chars("#>-"));

    // 创建一个流式解析器
    let mut stream = Deserializer::from_reader(reader).into_iter::<Value>();

    // 逐个读取和处理JSON对象
    while let Some(item) = stream.next() {
        let output_file = output.clone();
        match item {
            Ok(value) => {
                // 动态处理字段并写入到jsonlines文件
                let line_len = to_string(&value)?.len();
                append_json_lines(output_file, [value])?;

                // 更新进度条（你可能需要根据实际数量来更新这个）
                pb.inc(line_len as u64);
            }
            Err(err) => {
                println!("Error: {}", err);
            }
        }
        break;
    }
    pb.finish_with_message("Completed.");
    Ok(())
}
